#define _CRT_SECURE_NO_WARNINGS
//#include "Queue.h"

//typedef char StackDataType;
//typedef struct Stack
//{
//	StackDataType* arr;
//	int top;
//	int capacity;
//}Stack;
//
//void StackInit(Stack* st);
//void StackDestroy(Stack* st);
//void StackPush(Stack* st, StackDataType x);
//void StackPop(Stack* st);
//StackDataType StackTop(Stack* st);
//int StackSize(Stack* st);
//bool StackEmpty(Stack* st);
//void StackPrint(Stack* st);
//
//
//void StackInit(Stack* st)
//{
//	st->arr = NULL;
//	st->capacity = 0;
//	st->top = 0;
//}
//void StackDestroy(Stack* st)
//{
//	free(st->arr);
//	st->arr = NULL;
//	st->top = 0;
//	st->capacity = 0;
//}
//
//void StackPush(Stack* st, StackDataType x)
//{
//	assert(st);
//	if (st->top == st->capacity)
//	{
//		int newcapacity = st->capacity == 0 ? 4 : 2 * st->capacity;
//		StackDataType* tmp = (StackDataType*)realloc(st->arr, newcapacity * sizeof(StackDataType));
//		if (tmp == NULL)
//		{
//			perror("realloc fail");
//			return;
//		}
//		st->arr = tmp;
//		st->capacity = newcapacity;
//	}
//	st->arr[st->top++] = x;
//}
//
//void StackPop(Stack* st)
//{
//	assert(st);
//	assert(st->top > 0);
//	st->top--;
//}
//StackDataType StackTop(Stack* st)
//{
//	return st->arr[st->top - 1];
//}
//
//int StackSize(Stack* st)
//{
//	return st->top;
//}
//
//bool StackEmpty(Stack* st)
//{
//	return st->top == 0;
//}
//
//void StackPrint(Stack* st)
//{
//	while (!StackEmpty(st))
//	{
//		printf("%d ", StackTop(st));
//		StackPop(st);
//	}
//	printf("\n");
//}
//
//bool isValid(char* s) {
//	Stack st;
//	StackInit(&st);
//	while (*s)
//	{
//		if (*s == '(' || *s == '{' || *s == '[')
//			StackPush(&st, *s);
//		else
//		{
//			if (StackEmpty(&st))
//			{
//				StackDestroy(&st);
//				return false;
//			}
//			char ch = StackTop(&st);
//			StackPop(&st);
//			if ((ch == '(' && *s != ')') || (ch == '[' && *s != ']') || (ch == '{' && *s != '}'))
//			{
//				StackDestroy(&st);
//				return false;
//			}
//		}
//		s++;
//	}
//	if (!StackEmpty(&st))
//	{
//		StackDestroy(&st);
//		return false;
//	}
//	return true;
//}


//int main()
//{
//	Queue q;
//	QueueInit(&q);
//	QueuePush(&q, 1);
//	QueuePush(&q, 2);
//	QueuePush(&q, 3);
//	QueuePush(&q, 4);
//	printf("%d ", QueueBack(&q));
//	while (!QueueEmpty(&q))
//	{
//		printf("%d ", QueueFront(&q));
//		QueuePop(&q);
//	}
//	QueueDestroy(&q);
//
//	return 0;
//}
//
//
//
//
//typedef struct {
//    Queue q1;
//    Queue q2;
//} MyStack;
//
//
//MyStack* myStackCreate() {
//    MyStack* ret = (MyStack*)malloc(sizeof(MyStack));
//    QueueInit(&ret->q1);
//    QueueInit(&ret->q2);
//    return ret;
//}

//void myStackPush(MyStack* obj, int x) {
//    Queue* empty = &obj->q1;
//    Queue* nonempty = &obj->q2;
//    if (QueueEmpty(&obj->q2))
//    {
//        empty = &obj->q2;
//        nonempty = &obj->q1;
//    }
//    QueuePush(nonempty, x);
//}
//
//int myStackPop(MyStack* obj) {
//    Queue* empty = &obj->q1;
//    Queue* nonempty = &obj->q2;
//    if (QueueEmpty(&obj->q2))
//    {
//        empty = &obj->q2;
//        nonempty = &obj->q1;
//    }
//    while (QueueSize(nonempty) - 1)
//    {
//        int move = QueueFront(nonempty);
//        QueuePop(nonempty);
//        QueuePush(empty, move);
//    }
//    int ret = QueueFront(nonempty);
//    QueuePop(nonempty);
//    return ret;
//}
//
//int myStackTop(MyStack* obj) {
//    Queue* empty = &obj->q1;
//    Queue* nonempty = &obj->q2;
//    if (QueueEmpty(&obj->q2))
//    {
//        empty = &obj->q2;
//        nonempty = &obj->q1;
//    }
//    return QueueBack(nonempty);
//}
//
//bool myStackEmpty(MyStack* obj) {
//    return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
//}
//
//void myStackFree(MyStack* obj) {
//    QueueDestroy(&obj->q1);
//    QueueDestroy(&obj->q2);
//}




//typedef struct {
//    Stack st1;//push
//    Stack st2;//pop
//} MyQueue;
//
//
//MyQueue* myQueueCreate() {
//    MyQueue* ret = (MyQueue*)malloc(sizeof(MyQueue));
//    StackInit(&ret->st1);
//    StackInit(&ret->st2);
//    return ret;
//}
//
//void myQueuePush(MyQueue* obj, int x) {
//    StackPush(&obj->st1, x);
//}
//
//int myQueuePop(MyQueue* obj) {
//    if (StackEmpty(&obj->st2))
//    {
//        while (!StackEmpty(&obj->st1))
//        {
//            int move = StackTop(&obj->st1);
//            StackPop(&obj->st1);
//            StackPush(&obj->st2, move);
//        }
//    }
//    int ret = StackTop(&obj->st2);
//    StackPop(&obj->st2);
//    return ret;
//}
//
//int myQueuePeek(MyQueue* obj) {
//    if (StackEmpty(&obj->st2))
//    {
//        while (!StackEmpty(&obj->st1))
//        {
//            int move = StackTop(&obj->st1);
//            StackPop(&obj->st1);
//            StackPush(&obj->st2, move);
//        }
//    }
//    int ret = StackTop(&obj->st2);
//    return ret;
//}
//
//bool myQueueEmpty(MyQueue* obj) {
//    return StackEmpty(&obj->st1) && StackEmpty(&obj->st2);
//}
//
//void myQueueFree(MyQueue* obj) {
//    StackDestroy(&obj->st1);
//    StackDestroy(&obj->st2);
//}


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct {
    int* arr;
    int head;
    int tail;
    int size;
} MyCircularQueue;



MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* ret = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    ret->arr = (int*)malloc(sizeof(int) * (k + 1));
    ret->head = ret->tail = 0;
    ret->size = k + 1;
    return ret;
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    //    if(obj->head==obj->tail)
    //        return true;
    //    return false;
    return obj->head == obj->tail;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->tail + 1) % (obj->size) == obj->head;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if (myCircularQueueIsFull(obj))
        return false;
    obj->arr[obj->tail++] = value;
    obj->tail = (obj->tail) % (obj->size);
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if (obj->tail == obj->head)
        return false;
    obj->head = (obj->head + 1) % obj->size;
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if (obj->head == obj->tail)
        return -1;
    return obj->arr[obj->head];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if (obj->tail == obj->head)
        return -1;
    return obj->arr[(obj->tail - 1 + obj->size) % obj->size];
}



void myCircularQueueFree(MyCircularQueue* obj) {
    if (obj)
        free(obj->arr);
    free(obj);
}

int main()
{
    MyCircularQueue* tmp = myCircularQueueCreate(3);
    myCircularQueueEnQueue(tmp,1);
    myCircularQueueEnQueue(tmp,2);
    myCircularQueueEnQueue(tmp,3);
    myCircularQueueEnQueue(tmp,4);


}